/*
 * @Author: 抱
 * @Date: 2025-05-26 17:19:31
 * @LastEditors: 抱着羊啃 1437670973@qq.com
 * @LastEditTime: 2025-06-03 21:01:41
 * @FilePath: \demo1\src\main\java\org\example\demo1\servlets\functionPage\ChapterServlet.java
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
package org.example.demo1.servlets.functionPage;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.example.demo1.Entity.Chapter;
import org.example.demo1.DAO.NovelDao;
import org.example.demo1.Entity.ChapterContent;
import org.example.demo1.utils.MybatisUtils;  // 假设使用 MyBatis 工具类管理会话
import org.apache.ibatis.session.SqlSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

// 导入Gson的TypeAdapter和LocalDateTime相关类
import com.google.gson.TypeAdapter;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

@WebServlet("/API/Chapter")
public class ChapterServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求和响应的字符编码
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        Map<String, Object> result = new HashMap<>();

        // 获取小说 ID 参数
        String novelIdStr = req.getParameter("novelId");
        int novelId = -1;
        if (novelIdStr != null && !novelIdStr.isEmpty()) {
            try {
                novelId = Integer.parseInt(novelIdStr);
            } catch (NumberFormatException e) {
                // 处理无效的 novelId 参数
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                result.put("code", 400);
                result.put("msg", "Invalid novelId parameter.");
                out.write(new Gson().toJson(result));
                return;
            }
        }

        if (novelId == -1) {
            // 如果没有提供 novelId 参数，返回错误
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            result.put("code", 400);
            result.put("msg", "Missing novelId parameter.");
            out.write(new Gson().toJson(result));
            return;
        }

        SqlSession sqlSession = null;
        try {
            sqlSession = MybatisUtils.getSqlSession();
            NovelDao novelDao = sqlSession.getMapper(NovelDao.class);

            // 创建参数Map（匹配NovelDao.xml中getAllChaptersByNovelId的parameterType=map）
            Map<String, Object> params = new HashMap<>();
            params.put("novelId", novelId);
            params.put("chapterStatus", null);  // null表示不限制章节状态

            // 调用 DAO 方法获取所有章节（不限制状态）
            List<Chapter> chapters = novelDao.getAllChaptersByNovelId(params);

            // 配置Gson支持LocalDateTime序列化（使用ISO格式）
            Gson gson = new GsonBuilder()
                .registerTypeAdapter(LocalDateTime.class, new TypeAdapter<LocalDateTime>() {
                    private final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
                    @Override
                    public void write(JsonWriter out, LocalDateTime value) throws IOException {
                        out.value(formatter.format(value));
                    }
                    @Override
                    public LocalDateTime read(JsonReader in) throws IOException {
                        return LocalDateTime.parse(in.nextString(), formatter);
                    }
                })
                .create();

            // 构建统一响应结构
            result.put("code", 200);
            result.put("msg", "查询成功");
            result.put("total", chapters.size());
            // 修改为前端期望的 data 字段
            result.put("data", chapters); 

            // 转换为 JSON 并返回
            out.write(gson.toJson(result));

        } catch (Exception e) {
            e.printStackTrace();
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            result.put("code", 500);
            result.put("msg", "An error occurred while retrieving chapters.");
            out.write(new Gson().toJson(result));
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
    }
    
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 设置请求和响应的字符编码
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("application/json;charset=UTF-8");
        PrintWriter out = resp.getWriter();
        Map<String, Object> result = new HashMap<>();
        
        // 获取请求参数
        String action = req.getParameter("action");
        
        if ("create".equals(action)) {
            createChapter(req, resp, result, out);
        } else if ("update".equals(action)) {
            updateChapter(req, resp, result, out);
        } else {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            result.put("code", 400);
            result.put("msg", "Invalid action parameter.");
            out.write(new Gson().toJson(result));
        }
    }
    
    /**
     * 创建章节
     */
    private void createChapter(HttpServletRequest req, HttpServletResponse resp, 
                              Map<String, Object> result, PrintWriter out) throws IOException {
        SqlSession sqlSession = null;
        try {
            // 获取参数
            String novelIdStr = req.getParameter("novelId");
            String chapterTitle = req.getParameter("chapterTitle");
            String content = req.getParameter("content");
            String volumeName = req.getParameter("volumeName");
            
            // 参数验证
            if (novelIdStr == null || chapterTitle == null || chapterTitle.trim().isEmpty()) {
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                result.put("code", 400);
                result.put("msg", "缺少必要参数：novelId 或 chapterTitle");
                out.write(new Gson().toJson(result));
                return;
            }
            
            int novelId = Integer.parseInt(novelIdStr);

            
            sqlSession = MybatisUtils.getSqlSession();
            NovelDao novelDao = sqlSession.getMapper(NovelDao.class);
            
            // 获取下一个章节序号
            Integer maxChapterNumber = novelDao.getMaxChapterNumberByNovelId(novelId);
            int nextChapterNumber = (maxChapterNumber != null ? maxChapterNumber : 0) + 1;
            
            // 创建章节对象
            Chapter chapter = new Chapter();
            chapter.setNovel_id(novelId);
            chapter.setChapter_number(nextChapterNumber);
            chapter.setChapter_title(chapterTitle.trim());
            chapter.setWord_count(content != null ? content.length() : 0);
            chapter.setVolume_name(volumeName);
            
            // 插入章节
            int chapterResult = novelDao.insertChapter(chapter);
            
            if (chapterResult > 0 && chapter.getChapter_id() != null) {
                // 如果有内容，插入章节内容
                if (content != null && !content.trim().isEmpty()) {
                    ChapterContent chapterContent = new ChapterContent();
                    chapterContent.setChapter_id(chapter.getChapter_id());
                    chapterContent.setContent(content.trim());
                    
                    novelDao.insertChapterContent(chapterContent);
                }
                
                sqlSession.commit();
                
                result.put("code", 200);
                result.put("msg", "章节创建成功");
                // 替换为传统写法
                Map<String, Object> data = new HashMap<>();
                data.put("chapterId", chapter.getChapter_id());
                result.put("data", data);
            } else {
                sqlSession.rollback();
                result.put("code", 500);
                result.put("msg", "章节创建失败");
            }
            
        } catch (NumberFormatException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            result.put("code", 400);
            result.put("msg", "无效的数字参数");
        } catch (Exception e) {
            e.printStackTrace();
            if (sqlSession != null) {
                sqlSession.rollback();
            }
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            result.put("code", 500);
            result.put("msg", "服务器内部错误：" + e.getMessage());
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        
        out.write(new Gson().toJson(result));
    }
    
    /**
     * 更新章节
     */
    private void updateChapter(HttpServletRequest req, HttpServletResponse resp, 
                              Map<String, Object> result, PrintWriter out) throws IOException {
        SqlSession sqlSession = null;
        try {
            // 获取参数
            String chapterIdStr = req.getParameter("chapterId");
            String chapterTitle = req.getParameter("chapterTitle");
            String content = req.getParameter("content");
            String statusStr = req.getParameter("status");
            
            // 参数验证
            if (chapterIdStr == null || chapterTitle == null || chapterTitle.trim().isEmpty()) {
                resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
                result.put("code", 400);
                result.put("msg", "缺少必要参数：chapterId 或 chapterTitle");
                out.write(new Gson().toJson(result));
                return;
            }
            
            int chapterId = Integer.parseInt(chapterIdStr);
            int chapterStatus = "已发布".equals(statusStr) ? 0 : 1; // 0:已发布, 1:草稿
            
            sqlSession = MybatisUtils.getSqlSession();
            NovelDao novelDao = sqlSession.getMapper(NovelDao.class);
            
            // 更新章节信息
            Chapter chapter = new Chapter();
            chapter.setChapter_id(chapterId);
            chapter.setChapter_title(chapterTitle.trim());
            chapter.setWord_count(content != null ? content.length() : 0);
            chapter.setChapter_status(chapterStatus);
            
            int chapterResult = novelDao.updateChapter(chapter);
            
            if (chapterResult > 0) {
                // 更新章节内容
                if (content != null) {
                    ChapterContent chapterContent = new ChapterContent();
                    chapterContent.setChapter_id(chapterId);
                    chapterContent.setContent(content.trim());
                    
                    // 先尝试更新，如果没有记录则插入
                    int contentResult = novelDao.updateChapterContent(chapterContent);
                    if (contentResult == 0) {
                        novelDao.insertChapterContent(chapterContent);
                    }
                }
                
                sqlSession.commit();
                
                result.put("code", 200);
                result.put("msg", "章节更新成功");
                // 替换为传统写法
                Map<String, Object> data = new HashMap<>();
                data.put("chapterId", chapterId);
                result.put("data", data);
            } else {
                sqlSession.rollback();
                result.put("code", 404);
                result.put("msg", "章节不存在或更新失败");
            }
            
        } catch (NumberFormatException e) {
            resp.setStatus(HttpServletResponse.SC_BAD_REQUEST);
            result.put("code", 400);
            result.put("msg", "无效的数字参数");
        } catch (Exception e) {
            e.printStackTrace();
            if (sqlSession != null) {
                sqlSession.rollback();
            }
            resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            result.put("code", 500);
            result.put("msg", "服务器内部错误：" + e.getMessage());
        } finally {
            if (sqlSession != null) {
                sqlSession.close();
            }
        }
        
        out.write(new Gson().toJson(result));
    }
}